package io.fathom.cloud.identity.api.os.resources; import io.fathom.cloud.CloudException; import io.fathom.cloud.identity.api.os.model.v3.Domain; import io.fathom.cloud.identity.api.os.model.v3.Token; import io.fathom.cloud.identity.api.os.model.v3.Token.ProjectInfo; import io.fathom.cloud.identity.api.os.model.v3.Token.RoleInfo; import io.fathom.cloud.identity.api.os.model.v3.Token.UserInfo; import io.fathom.cloud.identity.model.AuthenticatedUser; import io.fathom.cloud.identity.services.TokenUtils; import io.fathom.cloud.identity.state.AuthRepository; import io.fathom.cloud.protobuf.CloudCommons.TokenInfo; import io.fathom.cloud.protobuf.IdentityModel.DomainData; import io.fathom.cloud.protobuf.IdentityModel.ProjectData; import io.fathom.cloud.protobuf.IdentityModel.RoleData; import io.fathom.cloud.protobuf.IdentityModel.UserData; import io.fathom.cloud.server.auth.TokenAuth; import java.util.List; import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.inject.persist.Transactional; @Path("/openstack/identity/v3/auth/tokens") @Transactional @Produces({ "application/json" }) public class TokensResource extends IdentityResourceBase { private static final Logger log = LoggerFactory.getLogger(TokensResource.class); // Should use identity service instead @Deprecated @Inject AuthRepository authRepository; @Inject TokenUtils tokenUtils; @GET @Produces({ JSON }) public Response getTokenInfo(@HeaderParam("x-auth-token") String authToken, @HeaderParam("x-subject-token") String subjectToken) throws CloudException { if (Strings.isNullOrEmpty(authToken) || Strings.isNullOrEmpty(subjectToken)) { throw new WebApplicationException(Status.BAD_REQUEST); } if (!authToken.equals(subjectToken)) { // For now, we only allow same-token auth throw new UnsupportedOperationException(); } AuthenticatedUser auth = loginService.authenticate(authToken); if (auth == null) { throw new WebApplicationException(Status.UNAUTHORIZED); } TokenInfo subject = tokenService.findValidToken(subjectToken); if (subject == null) { throw new WebApplicationException(Status.NOT_FOUND); } ResponseBuilder response = Response.ok(); response.entity(buildTokenModel(subject)); return response.build(); } private Token buildTokenModel(TokenInfo token) throws CloudException { Preconditions.checkNotNull(token); Token response = new Token(); response.expires = TokenAuth.getExpiration(token); UserData user = authRepository.getUsers().find(token.getUserId()); if (user == null) { throw new IllegalStateException(); } DomainData domain = authRepository.getDomains().find(user.getDomainId()); if (domain == null) { throw new IllegalStateException(); } response.user = toModel(domain, user); List<RoleData> roles = null; switch (token.getTokenScope()) { case Domain: { // Domain scoped DomainData scope = authRepository.getDomains().find(token.getDomainId()); if (scope == null) { throw new IllegalStateException(); } response.domainScope = toModel(domain); response.serviceCatalog = loginService.buildServiceMap(getBaseUrl(), null); break; } case Project: { // Project scoped ProjectData scope = authRepository.getProjects().find(token.getProjectId()); if (scope == null) { throw new IllegalStateException(); } DomainData projectDomain = authRepository.getDomains().find(scope.getDomainId()); if (projectDomain == null) { throw new IllegalStateException(); } response.projectScope = toModel(projectDomain, scope); response.serviceCatalog = loginService.buildServiceMap(getBaseUrl(), scope); roles = tokenUtils.getProjectRoles(user, scope.getId()); break; } default: break; } if (roles != null) { response.roles = Lists.newArrayList(); for (RoleData role : roles) { RoleInfo model = toModel(role); response.roles.add(model); } } return response; } private RoleInfo toModel(RoleData role) { RoleInfo model = new RoleInfo(); model.id = Long.toString(role.getId()); model.name = role.getName(); return model; } private UserInfo toModel(DomainData domain, UserData user) { UserInfo model = new UserInfo(); model.id = Long.toString(user.getId()); model.name = user.getName(); model.domain = toModel(domain); return model; } private Domain toModel(DomainData domain) { Domain model = new Domain(); model.id = Long.toString(domain.getId()); model.name = domain.getName(); return model; } private ProjectInfo toModel(DomainData domain, ProjectData project) { ProjectInfo model = new ProjectInfo(); model.id = Long.toString(project.getId()); model.name = project.getName(); model.domain = toModel(domain); return model; } }